#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define SNAKE_MAX_LENGTH 20
#define SNAKE_HEAD 'H'
#define SNAKE_BODY 'X'
#define BLANK_CELL ' '
#define SNAKE_FOOD '$'
#define WALL_CELL '*'

//地图
char map[12][12] = {
    "************",
    "*XXXXH     *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "*          *",
    "************"};

//蛇的位置与长度
int snakeX[SNAKE_MAX_LENGTH] = {1, 2, 3, 4, 5};
int snakeY[SNAKE_MAX_LENGTH] = {1, 1, 1, 1, 1};
int snakeLength = 5;

void output();                   //输出模块
void gameover();                 //游戏结束的输出
void operation();                //操作的读取和解析
int GameRun(int addX, int addY); //游戏规则的判断
void Move(int addX, int addY);   //蛇的移动控制器

//主函数
int main()
{
    output();
    operation();
    gameover();
}

void output()
{
    printf("\n------------Gready Snake------------\n");
    for (int i = 0; i < 12; i++)
    {
        for (int j = 0; j < 12; j++)
        {
            printf("%c", map[i][j]);
        }
        printf("\n");
    }
}

void gameover()
{
    printf("Game Over!\n");
}

void operation()
{
    char c;
    char lastc = 'd';
    int addX = 0;
    int addY = 0;
    int flag;

    printf("Please input the operation(WASD/wasd): ");
    while (scanf(" %c", &c)) //不断读取指令
    {
        flag = 0;
        switch (c) //判断方向
        {
        case 'a':
        case 'A':
            if (lastc == 'd' || lastc == 'D')
            {
                flag = 1;
                break;
            }
            else
            {
                addX = -1;
                addY = 0;
                break;
            }

        case 'd':
        case 'D':
            if (lastc == 'a' || lastc == 'A')
            {
                flag = 1;
                break;
            }
            else
            {
                addX = 1;
                addY = 0;
                break;
            }

        case 'w':
        case 'W':
            if (lastc == 's' || lastc == 'S')
            {
                flag = 1;
                break;
            }
            else
            {
                addX = 0;
                addY = -1;
                break;
            }

        case 's':
        case 'S':
            if (lastc == 'w' || lastc == 'W')
            {
                flag = 1;
                break;
            }
            else
            {
                addX = 0;
                addY = 1;
                break;
            }

        default:
            flag = 2;
            break;
        }
        //异常处理，错误输入和错误移动：
        if (flag == 2)
        {
            printf("Invalid Input! Please input again(WASD/wasd): ");
            continue;
        }
        if (flag == 1)
        {
            printf("Invalid Move! Please input again(WASD/wasd): ");
            continue;
        }
        //游戏终止条件判断，1继续，0返回
        if (!GameRun(addX, addY))
        {
            break;
        }
        //继续输出
        output();
        printf("Please input the operation(WASD/wasd): ");
        //保存上次的输入操作值
        lastc = c;
    }
}

int GameRun(int addX, int addY)
{
    Move(addX, addY);
    return 1;
}

void Move(int addX, int addY)
{
    map[snakeY[0]][snakeX[0]] = BLANK_CELL;                             //蛇尾去除
    map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] = SNAKE_BODY; //原来的头变成身体
    for (int i = 0; i < snakeLength - 1; i++)
    { //蛇身整体移动一格
        snakeX[i] = snakeX[i + 1];
        snakeY[i] = snakeY[i + 1];
    }
    snakeX[snakeLength - 1] += addX; //找头的位置
    snakeY[snakeLength - 1] += addY;
    map[snakeY[snakeLength - 1]][snakeX[snakeLength - 1]] = SNAKE_HEAD;
}